package com.zt.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zt.entity.Coupons;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 优惠券缓存工具类
 * 按照指定格式将用户优惠券信息存储到Redis中
 */
@Component
@Slf4j
public class CouponCacheUtil {
    
    @Autowired
    @Qualifier("stringRedisTemplate")
    private StringRedisTemplate redisTemplate;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    // Redis键前缀
    private static final String COUPONS_KEY_PREFIX = "coupons:";
    
    // 默认过期时间（天）
    private static final int DEFAULT_EXPIRE_DAYS = 6;
    
    /**
     * 将优惠券信息缓存到Redis中（按指定格式）
     * @param userId 用户ID
     * @param coupons 优惠券列表
     * @param expireDays 过期天数，如果为null则使用默认6天
     */
    public void cacheUserCoupons(Long userId, List<Coupons> coupons, Integer expireDays) {
        try {
            if (userId == null || coupons == null) {
                log.warn("用户ID或优惠券列表为空，跳过缓存");
                return;
            }
            
            // 转换为指定格式的Map列表
            List<Map<String, Object>> couponDetailList = new ArrayList<>();
            for (Coupons coupon : coupons) {
                Map<String, Object> couponDetail = convertCouponToMap(coupon);
                couponDetailList.add(couponDetail);
            }
            
            // 缓存到Redis
            String couponsKey = COUPONS_KEY_PREFIX + userId;
            String couponsJson = objectMapper.writeValueAsString(couponDetailList);
            
            int expireDaysToUse = expireDays != null ? expireDays : DEFAULT_EXPIRE_DAYS;
            redisTemplate.opsForValue().set(couponsKey, couponsJson, expireDaysToUse, TimeUnit.DAYS);
            
            log.info("用户 {} 的优惠券已缓存到Redis，数量: {}，过期时间: {}天", userId, coupons.size(), expireDaysToUse);
        } catch (Exception e) {
            log.error("为用户 {} 缓存优惠券失败: {}", userId, e.getMessage(), e);
        }
    }
    
    /**
     * 添加单个优惠券到用户的Redis缓存中
     * @param userId 用户ID
     * @param coupon 优惠券信息
     * @param expireDays 过期天数，如果为null则使用默认6天
     */
    public void addCouponToUserCache(Long userId, Coupons coupon, Integer expireDays) {
        try {
            if (userId == null || coupon == null) {
                log.warn("用户ID或优惠券信息为空，跳过添加");
                return;
            }
            
            String couponsKey = COUPONS_KEY_PREFIX + userId;
            
            // 获取现有的优惠券列表
            List<Map<String, Object>> existingCoupons = getUserCouponsFromCache(userId);
            
            // 检查是否已存在相同ID的优惠券
            boolean exists = existingCoupons.stream()
                .anyMatch(existingCoupon -> coupon.getId().equals(existingCoupon.get("id")));
            
            if (!exists) {
                // 添加新优惠券
                Map<String, Object> couponDetail = convertCouponToMap(coupon);
                existingCoupons.add(couponDetail);
                
                // 重新缓存
                String couponsJson = objectMapper.writeValueAsString(existingCoupons);
                int expireDaysToUse = expireDays != null ? expireDays : DEFAULT_EXPIRE_DAYS;
                redisTemplate.opsForValue().set(couponsKey, couponsJson, expireDaysToUse, TimeUnit.DAYS);
                
                log.info("用户 {} 添加优惠券成功，优惠券ID: {}，过期时间: {}天", userId, coupon.getId(), expireDaysToUse);
            } else {
                log.debug("用户 {} 已拥有优惠券 {}，跳过添加", userId, coupon.getId());
            }
        } catch (Exception e) {
            log.error("为用户 {} 添加优惠券 {} 失败: {}", userId, coupon.getId(), e.getMessage(), e);
        }
    }
    
    /**
     * 从Redis获取用户的优惠券列表
     * @param userId 用户ID
     * @return 用户的优惠券详细信息列表
     */
    public List<Map<String, Object>> getUserCouponsFromCache(Long userId) {
        try {
            if (userId == null) {
                return new ArrayList<>();
            }
            
            String couponsKey = COUPONS_KEY_PREFIX + userId;
            String couponsJson = redisTemplate.opsForValue().get(couponsKey);
            
            if (couponsJson != null && !couponsJson.isEmpty()) {
                List<Map<String, Object>> coupons = objectMapper.readValue(
                    couponsJson, 
                    objectMapper.getTypeFactory().constructCollectionType(List.class, Map.class)
                );
                return coupons;
            }
        } catch (Exception e) {
            log.error("获取用户 {} 的优惠券缓存失败: {}", userId, e.getMessage(), e);
        }
        return new ArrayList<>();
    }
    
    /**
     * 删除用户的优惠券缓存
     * @param userId 用户ID
     */
    public void deleteUserCouponsCache(Long userId) {
        try {
            if (userId == null) {
                return;
            }
            
            String couponsKey = COUPONS_KEY_PREFIX + userId;
            redisTemplate.delete(couponsKey);
            log.debug("删除用户 {} 的优惠券缓存", userId);
        } catch (Exception e) {
            log.error("删除用户 {} 的优惠券缓存失败: {}", userId, e.getMessage(), e);
        }
    }
    
    /**
     * 将Coupons对象转换为指定格式的Map
     * @param coupon 优惠券对象
     * @return 转换后的Map
     */
    private Map<String, Object> convertCouponToMap(Coupons coupon) {
        Map<String, Object> couponMap = new HashMap<>();
        
        couponMap.put("id", coupon.getId());
        couponMap.put("title", coupon.getTitle());
        couponMap.put("description", coupon.getDescription());
        couponMap.put("type", coupon.getType());
        couponMap.put("amount", coupon.getAmount());
        couponMap.put("minSpend", coupon.getMinSpend());
        
        // 转换时间为时间戳（毫秒）
        if (coupon.getStartTime() != null) {
            couponMap.put("startTime", coupon.getStartTime().getTime());
        }
        if (coupon.getEndTime() != null) {
            couponMap.put("endTime", coupon.getEndTime().getTime());
        }
        
        couponMap.put("status", coupon.getStatus());
        
        return couponMap;
    }
    
    /**
     * 为新用户发放默认优惠券（参考您提供的代码）
     * @param userId 用户ID
     * @param defaultCoupon 默认优惠券
     */
    public void giveNewUserCoupon(Long userId, Coupons defaultCoupon) {
        try {
            if (defaultCoupon == null) {
                log.warn("默认优惠券不存在，用户ID: {}", userId);
                return;
            }
            
            List<Coupons> couponsList = new ArrayList<>();
            couponsList.add(defaultCoupon);
            
            // 将优惠券列表存储到Redis，设置6天过期时间
            cacheUserCoupons(userId, couponsList, 6);
            
            log.info("新用户 {} 注册成功，已自动发放优惠券，ID: {}", userId, defaultCoupon.getId());
        } catch (Exception e) {
            log.error("为新用户 {} 发放优惠券失败: {}", userId, e.getMessage(), e);
        }
    }
}
